package xyz.lwm.lazycat.beans;

import lombok.Getter;
import xyz.lwm.lazycat.setting.Setting;
import xyz.lwm.lazycat.utility.StringUtil;
import xyz.lwm.lazycat.utility.convert.Convert;
import xyz.lwm.lazycat.utility.reflect.TypeUtil;

import java.lang.reflect.Type;

/**
 * <h3>给实例注入属性</h3>
 * <p>用于注入 setting 值</p>
 * <pre>{@code
 * @Bean
 * public class TestService {
 *      @Value(${db.name:postgres})
 *      private String dbName;
 * }
 *
 * }</pre>
 *
 * @see xyz.lwm.lazycat.annotation.Value
 * @author lwm
 */
@Getter
public class ValueInjection extends Injection {

    /**
     * Value 注解的表达式
     */
    private final String expr;

    public ValueInjection(Class<?> owner, String name, Type type, String property, String expr) {
        super(owner, name, type, property);
        this.expr = expr;
    }

    @Override
    public Object apply(BeanRefs beanRefs) {
        if (StringUtil.isBlank(expr)) {
            return expr;
        }
        String exprStr = expr.trim();
        if (!exprStr.startsWith("${")) {
            return expr;
        }

        String exprValue = exprStr.substring(2, exprStr.length() - 1);
        int i = exprValue.indexOf(":");
        String key = i > 0 ? exprValue.substring(0, i).trim() : exprValue.trim();
        String defaultValue = i > 0 ? exprValue.substring(i + 1).trim() : null;

        return Setting.get().get(key).orElse(defaultValue)
                .let(v -> Convert.to(v, TypeUtil.getClass(getType()))).getOr(null);
    }

}
